package com.milo.stream;


import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author: Milogenius
 * @create: 2019-10-17 09:20
 * @description: 利用Stream重构代码演示
 **/
@Slf4j
public class RefactorTheCode {
    /**
     * 唱片集
     */
    private class Album {
        private String name;
        private ArrayList<Tracks> trackList;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public List<Tracks> getTrackList() {
            return trackList;
        }

        public void setTrackList(ArrayList<Tracks> trackList) {
            this.trackList = trackList;
        }

    }

    /**
     * 曲目
     */
    private class Tracks {
        private String name;
        private int length;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getLength() {
            return length;
        }

        public void setLength(int length) {
            this.length = length;
        }
    }

    /**
     *
     */
    @Test
    public void findLongTracksTest() {
        ArrayList<Album> alist = new ArrayList<>();
        ArrayList<Tracks> tList = new ArrayList<>();
        ArrayList<Tracks> sList = new ArrayList<>();

        Tracks track = new Tracks();
        track.setName("听妈妈的话");
        track.setLength(70);

        Tracks track1 = new Tracks();
        track1.setLength(50);
        track1.setName("东风破");

        tList.add(track);
        tList.add(track1);

        Album album = new Album();
        album.setName("一枝花");
        album.setTrackList(tList);
        alist.add(album);


        Tracks track2 = new Tracks();
        track2.setName("常回家看看");
        track2.setLength(80);

        Tracks track3 = new Tracks();
        track3.setLength(30);
        track3.setName("大风歌");

        sList.add(track2);
        sList.add(track3);

        Album album1 = new Album();
        album1.setName("一枝草");
        album1.setTrackList(sList);

        alist.add(album1);

        //常规方法
        RefactorTheCode refactorTheCode = new RefactorTheCode();
        Set<String> longTracks = refactorTheCode.findLongTracks(alist);
        log.info(JSONObject.toJSONString(longTracks));

        //重构第一步
        Set<String> longTracks1 = refactorTheCode.findLongTracks1(alist);
        log.info("重构第一步:{}",JSONObject.toJSONString(longTracks1));

        //重构第二步
        Set<String> longTracks2 = refactorTheCode.findLongTracks2(alist);
        log.info("重构第二步:{}",JSONObject.toJSONString(longTracks2));

    }
    /**
     * 找出长度大于1的曲目
     * @param albums 曲目
     * @return
     */
    public Set<String> findLongTracks(List<Album> albums){
        Set<String> tracksNames = new HashSet<>();
        for (Album album:albums) {
            for (Tracks track:album.getTrackList()) {
                if (track.getLength()>60) {
                    String name = track.getName();
                    tracksNames.add(name);
                }
            }
        }
        return tracksNames;
    }

    /**
     * 重构第一步:使用Stream的forEach方法替换掉for循环
     * 找出长度大于60的曲目
     * @param albums 曲目
     * @return
     */
    public Set<String> findLongTracks1(List<Album> albums){
        Set<String> tracksNames = new HashSet<>();
        albums.stream().forEach(album -> {
            album.getTrackList().forEach(track -> {
                if (track.getLength()>60) {
                    String name = track.getName();
                    tracksNames.add(name);
                }
            });
        });
        return tracksNames;
    }

    /**
     * 重构第二步
     * 找出长度大于60的曲目
     * @param albums 曲目
     * @return
     */
    public Set<String> findLongTracks2(List<Album> albums){
        Set<String> tracksNames = new HashSet<>();
        albums.stream().forEach(album -> {
            album.getTrackList()
                    .stream()
                    .filter(track -> track.getLength()>60)
                    .map(track -> track.getName())
                    .forEach(name -> tracksNames.add(name));
        });
        return tracksNames;
    }

    /**
     * 重构第三步
     * 找出长度大于60的曲目
     * @param albums 曲目
     * @return
     */
    public Set<String> findLongTracks3(List<Album> albums){
        Set<String> tracksNames = new HashSet<>();
        albums.stream()
                .flatMap(album -> album.getTrackList().stream())
                .filter(track -> track.getLength()>60)
                .map(track -> track.getName())
                .forEach(name -> tracksNames.add(name));
        return tracksNames;
    }

    /**
     * 重构第四步
     * 找出长度大于60的曲目
     * @param albums 曲目
     * @return
     */
    public Set<String> findLongTracks4(List<Album> albums){
        Set<String> tracksNames = new HashSet<>();
        return albums.stream().flatMap(album -> album.getTrackList().stream())
                .filter(track -> track.getLength()>60).map(track -> track.getName())
                .collect(Collectors.toSet());
    }

}
